home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
mstrenv.zip
/
MSTR_ENV.H
< prev
Wrap
Text File
|
1993-01-04
|
10KB
|
290 lines
/**********************************************************************/
/* */
/* mstr_env.h MS 'C' ver. to get/put DOS master environment variables */
/* */
/* Purpose: Functions to deal with the DOS master (not local) envir-*/
/* onment. Ordinary getenv and putenv functions deal with */
/* the local environment; that can NOT be accessed from */
/* the DOS command line and batch files. This routine */
/* finds, reads, and writes to the master environment. */
/* */
/* Author: Scott Ladd, 302 N 12th Street, */
/* Gunnison, Colorado, 81230. */
/* */
/* Published: The C Users Journal, July, 1989, pages 59ff. */
/* */
/* Modified: T. E. McCormick, 06/89, for Microsoft C use only. */
/* Refer to the article mentioned above for additional */
/* details, Turbo C capability, etc. The changes are few. */
/* but many comments were left out since I was keying it */
/* in from the magazine! */
/* */
/**********************************************************************/
/**************** Global declarations ********************************/
char far * env_ptr; /* pointer: 1st byte global envir. */
static unsigned env_length; /* length of global environment. */
static int initialized = 0; /* tells if module was initialized.*/
static char s[256]; /* internal buffer for strings. */
static void m_findenv(void); /* function to find master envir. */
#define NUL '\x00' /* null char is string terminator. */
int env_len; /* length of global envir string */
/**************** Beginning of Microsoft-dependent code. **************/
/*** Sorry about removing the `if defined`s, but I was keying this ***/
/*** from the printed magazine article. I have omitted many useful ***/
/*** comments and the function headings documentation. Please refer **/
/*** to the July, 1989 C Users Journal available from the C Users ***/
/*** Group, 2120 W 25th Street, Suite B, Lawrence KS 66046-9972. ***/
/**********************************************************************/
/* Following macro must be generated for Microsoft C and Quick C. */
/* It will make a far pointer. Borland Turbo C provides MK_FP. */
/* This MK-FP function was modified from the published version. */
/****** MK_FP make far pointer function: see Borland TC dos.h file. ***/
#define MK_FP(seg,ofs) ((void far *) \
(((unsigned long)(seg) << 16) | (unsigned)(ofs)))
/****** poke and peek are humble attempts to emulate BASIC functions. */
#define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c))
#define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c))
#define peek(a,b) (*((int far*)MK_FP((a),(b))))
#define peekb(a,b) (*((char far*)MK_FP((a),(b))))
typedef struct
{
char reserved1[22];
unsigned par_seg; /* set of parent of current program */
char reserved2[20];
unsigned env_seg; /* environment seg: current program */
}
PSP;
/* Following pragma also required for Microsoft C and Quick C. */
/* It is essential to compile the MCB with byte, not word alignment. */
/* Borland Turbo C uses byte alignment, it must be forced with MSC. */
#pragma pack(1)
/**************** End of Microsoft-dependent code. **************/
typedef struct
{
char status; /* indicates if this block is in chain */
unsigned owner_psp; /* psp segment of this block`s owner. */
unsigned len; /* size in paragraphs of this memory block. */
}
MCB;
/**************** Beginning of Microsoft-dependent code. **************/
#pragma pack()
/**************** End of Microsoft-dependent code. **************/
/**************** Function declaration: **************/
char * m_getenv(char * name)
{
char far * e;
char * n;
int i;
if (!initialized) /* initialize if needed */
m_findenv();
e = env_ptr;
while (*e) /* search for name */
{
n = name;
while ((*e == *n) && (*e != '=') && (*e != NUL) && (*n != NUL))
{
++e;
++n;
}
if ((*n == NUL) && (*e == '=')) /* means we found name. */
{
++e;
/***** strcpy() can`t be used: pointer sizes may differ ****/
for (i = 0; (i < 256) && (*e != NUL); ++i)
{
s[i] = *e;
++e;
}
if (i < 256)
s[i] = NUL;
return s; /* contains value of name */
}
/***** skip to the next environment variable ****/
while (*e != NUL)
++e;
++e;
}
return NULL; /* name was not found */
}
/**************** Function declaration: m_putenv() **************/
int m_putenv(char *name, char *text)
{
char far * e;
unsigned l = 0;
char * sptr;
if (!initialized)
m_findenv();
e = env_ptr;
/***** check to insure storage reqd is less than 256 bytes *******/
if ((strlen(name) + 2 + strlen(text)) > 256)
return 1;
/***** make a complete environment string from components given *****/
strcpy(s,name);
/* strupr(s); */
strcat(s,"=");
strcat(s,text);
/***** delete any existing variables of the same name *****/
m_delenv(name);
/***** find the end of current variables marked by two NULLs *****/
e = env_ptr;
l = 0;
while (!((*e == NUL) && (*(e+1) == NUL)))
{
++e;
++l;
}
l = env_len - l - 1; /* will new string fit in environment? */
if (l < strlen(s))
return 1; /* return an error if variable won`t fit */
sptr = s;
++e; /* otherwise, copy onto the end of current envir. */
while (*sptr != NUL)
*e++ = *sptr++;
*e = NUL;
*(e + 1) = NUL;
return 0; /* it worked */
}
/**************** Function declaration: m_delenv() **************/
int m_delenv(char *name)
{
char far * e1; /* used in search: marks begin next variable */
char far * e2; /* marks beginning of the variable */
char * n; /* used in search: name pointer */
int searching = 1; /* flag to indicate search end */
if (!initialized)
m_findenv();
e1 = env_ptr;
/********* Find the beginning of the variable to be deleted. ******/
while ((*e1 != NUL) & (searching))
{
n = name;
e2 = e1;
while ((*e1 == *n) && (*e1 != '=') && (*e1 != NUL) && (*n != NUL))
{
++e1;
++n;
}
if ((!*n) && (*e1 == '='))
searching = 0; /* var we want was found: turn flag off */
while (*e1 != NUL)
++e1;
++e1;
}
/****** If the name was not found, return with an error. *****/
if ((*e1 == NUL) && (searching))
return 1;
/****** Otherwise, copy remainder of environment over variable *****/
while (!((*e1 == NUL) && (*(e1+1) == NUL)))
{
*e2 = *e1;
e2++;
e1++;
}
*e2 = NUL;
*(e2 + 1) = NUL; /* End the environment with double NUL bytes */
return 0; /* it worked */
}
/**************** Function declaration: m_findenv() **************/
static void m_findenv()
{
union REGS regs;
struct SREGS sregs;
/**** MCBs are Memory Control Blocks ****/
int far * SEGptr; /* set to addr of segment of first MCB */
MCB far * CONFIGmcb; /* set to addr of CONFIG`s MCB */
MCB far * SHELLmcb; /* set to addr of COMMAND.COM`s MCB */
MCB far * ENVmcb; /* set to addr of environment`s MCB */
PSP far * SHELLpsp; /* set to addr of COMMAND.COM`s PSP */
regs.h.ah = 0x52;
intdosx(®s,®s,&sregs);
SEGptr = MK_FP(sregs.es, regs.x.bx - 2);
CONFIGmcb = MK_FP(*SEGptr,0);
SHELLpsp = MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->len + 2, 0);
if (SHELLpsp->env_seg == 0)
{
/***** The environment is in the block AFTER the parent program */
SHELLmcb = MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->len + 1, 0);
env_ptr = MK_FP(FP_SEG(SHELLmcb) + SHELLmcb->len + 2, 0);
}
else
{
/***** Otherwise, we have a direct pointer to the envir block. */
env_ptr = MK_FP(SHELLpsp->env_seg, 0);
}
ENVmcb = MK_FP(FP_SEG(env_ptr) -1, 0); /* pointer: envir block MCB */
env_len = ENVmcb->len * 16; /* calc length of envir. */
initialized = 1; /* set init switch to on */
}
/********************************************************************/
/* set init switch to on */
}
/******************************************************